#define TOP 0
#define RIGHT 1
#define BOTTOM 2
#define LEFT 3
#define VERTICAL 0
#define HORIZONTAL 1

#include <iostream>
using namespace std;
#include <cstdlib>
#include <cstring>
#include <vector>
#include <cmath>

#include "Block.h"

class blockManager{
public:
  	blockManager(int, int);

	float x(int);
	float y(int);
	bool orientation(int);
	int side(int);
	bool exists(int);
	
	vector<int> getInfo(float, float);
	void destroy(int);
private:
	int depth, width;
	float center;
	vector<vector<vector<Block> > > blocks;
	vector<vector<int> > index;
};

blockManager::blockManager(int w, int d){
	depth = d;
	width = w;
	
	center = ((float)(3*width + depth))/2;
	
	blocks.resize(4);
	index.resize(depth*width*4);

	int current = 0;

	for(int p1 = 0; p1 < 4; p1++){
		blocks[p1].resize(width);
		for(int p2 = 0; p2 < width; p2++){
			blocks[p1][p2].resize(depth);
			for(int p3 = 0; p3 < depth; p3++){
				current = (p1*(depth*width) + p2*depth + p3);
				index[current].resize(3);
				index[current][0] = p1;
				index[current][1] = p2;
				index[current][2] = p3;
				if(p1 == TOP){
					blocks[p1][p2][p3].setX(depth + 3*p2);
					blocks[p1][p2][p3].setY(3*width + p3);
				}
				else if(p1 == RIGHT){
					blocks[p1][p2][p3].setX(3*width + p3);
					blocks[p1][p2][p3].setY(3*p2);
				}
				else if(p1 == BOTTOM){
					blocks[p1][p2][p3].setX(3*p2);
					blocks[p1][p2][p3].setY(p3);
				}
				else if(p1 == LEFT){
					blocks[p1][p2][p3].setX(p3);
					blocks[p1][p2][p3].setY(depth + 3*p2);
				}
				blocks[p1][p2][p3].setExists(true);
			}
		}
	}
}
float blockManager::x(int indexNum){
	int p1 = index[indexNum][0], p2 = index[indexNum][1], p3 = index[indexNum][2];
	int blockX = blocks[p1][p2][p3].x();
	
	float x;

	if(p1 == TOP || p1 == BOTTOM)
		x = 1.5 + (((float) blockX) - center);
	else
		x = .5 + (((float) blockX) - center);		

	return x;
}
float blockManager::y(int indexNum){
	int p1 = index[indexNum][0], p2 = index[indexNum][1], p3 = index[indexNum][2];
	int blockY = blocks[p1][p2][p3].y();
	
	float y;

	if(p1 == LEFT || p1 == RIGHT)
		y = 1.5 + (((float) blockY) - center);
	else
		y = .5 + (((float) blockY) - center);		

	return y;
}
bool blockManager::orientation(int indexNum){
	int p1 = index[indexNum][0];
	bool orient;

	if(p1 == TOP || p1 == BOTTOM)
		orient = HORIZONTAL;
	else
		orient = VERTICAL;
	
	return orient;
}
int blockManager::side(int indexNum){
	int p1 = index[indexNum][0];
	return p1;
}
bool blockManager::exists(int indexNum){
	int p1 = index[indexNum][0], p2 = index[indexNum][1], p3 = index[indexNum][2];
	bool blockExists = blocks[p1][p2][p3].exists();
	
	return blockExists;
}
vector<int> blockManager::getInfo(float bX, float bY){
	vector<int> info(2);
	
	int blockX = (int) (bX+center), blockY = (int) (bY+center), p1, p2, p3, indexNum;

	if(blockX > depth && blockY >= 3*width){
		blockX -= depth; 
		blockX -= blockX%3;

		p1 = TOP;
		p2 = blockX/3;
		p3 = (blockY-3*width);
	}
	else if(blockX >= 3*width){
		blockY -= blockY%3;

		p1 = RIGHT;
		p2 = blockY/3;
		p3 = (blockX-3*width);
	}
	else if(blockY < depth){
		blockX -= blockX%3;

		p1 = BOTTOM;
		p2 = blockX/3;
		p3 = blockY;
	}
	else if(blockX < depth){
		blockY -= depth; 
		blockY -= blockX%3;

		p1 = LEFT;
		p2 = blockY/3;
		p3 = blockX;
	}

	indexNum = (p1*(depth*width) + p2*depth + p3);
	info[0] = indexNum;

	float blockCenterX = x(indexNum), blockCenterY = y(indexNum);

	bX -= blockCenterX;
	bY -= blockCenterY;

	if(p1 == LEFT || p1 == RIGHT){
		if(bX < 0)
			info[1] = LEFT;
		else	
			info[1] = RIGHT;
	}
	else{
		if(bY < 0)
			info[1] = BOTTOM;
		else	
			info[1] = TOP;
	}
	return info;
}		
void blockManager::destroy(int indexNum){
	int p1 = index[indexNum][0], p2 = index[indexNum][1], p3 = index[indexNum][2];
	blocks[p1][p2][p3].setExists(false);

cout << indexNum << " destroyed\n" << endl;

}				
	
